package config;

import base.R;
import cn.hutool.core.util.ReflectUtil;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import utils.MapperProxy;
import utils.MapperUtils;

import javax.servlet.FilterChain;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.InputStream;
import java.util.Objects;
import java.util.Optional;
import java.util.Properties;

@Slf4j
@WebFilter
public class RequestFilter extends HttpFilter {

    @Override
    @SneakyThrows
    public void init() {
        // 读取配置文件
        InputStream resourceAsStream = this.getClass().getClassLoader().getResourceAsStream("mapperLocation.properties");
        Properties properties = new Properties();
        properties.load(resourceAsStream);
        String mapperPackageName = Optional.ofNullable(properties.getProperty("mapper.location"))
                .map(s -> s.replace(".", "/"))
                .orElseThrow(() -> new RuntimeException("mapper.location配置错误"));
        ClassLoader classLoader = this.getClass().getClassLoader();
        // 获取包下的所有类文件
        File[] files = new File(Objects.requireNonNull(classLoader.getResource(mapperPackageName)).toURI()).listFiles();

        // 遍历文件并加载类
        assert files != null;
        for (File file : files) {
            if (file.getName().endsWith(".class")) {
                // 获取类名
                String className = mapperPackageName + "." + file.getName().substring(0, file.getName().length() - 6);
                try {
                    // 加载类
                    Class<?> clazz = classLoader.loadClass(className);
                    log.info("添加缓存Mapper: {}", clazz.getName());
                    // 添加到缓存逻辑
                    Object proxy = MapperProxy.getInstance().getProxy(ReflectUtil.getConstructor(clazz).newInstance());
                    String entityClassName = ReflectUtil.getFieldValue(proxy, "clazz").toString().split(" ")[1];
                    MapperUtils.set(Class.forName(entityClassName), proxy);
                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
                }
            }
        }
        log.info("初始化完成");
        log.info("当前Mapper容器：{}", MapperUtils.show());
    }

    @Override
    protected void doFilter(HttpServletRequest req, HttpServletResponse res, FilterChain chain) {
        try {
            res.setCharacterEncoding("UTF-8");
            req.setCharacterEncoding("UTF-8");
            chain.doFilter(req, res);
        } catch (Exception e) {
            R.error().setMsg("请求时出现异常: " + e.getMessage()).push(res);
        }
    }


}
